#!/usr/bin/php -q
<?php
include("jphpframework.php");
include("jphpframework_builder.inc");

if(in_array($_SERVER['argv'][1], array('-h', '--help'))){
    echo "\nParam 1: directory\n".
         "Param 2: database server (e.g. localhost)\n".
         "Param 3: database name\n".
         "Param 4: database username\n".
         "Param 5: database password\n\n";
    exit;
}

if(count($_SERVER['argv']) < 6){
    echo "PARAMETER ERROR\nUse -h or --help for more information\n";
    exit;
}

$fromdir = "builder_files/";

$dir = $_SERVER["argv"][1];
$dbserver = $_SERVER['argv'][2];
$dbname = $_SERVER['argv'][3];
$dbuser = $_SERVER['argv'][4];
$dbpass = $_SERVER['argv'][5];



$config = "<?php
\$dsn = array('dbtype'=>'mysqli',
             'host'=>'{$dbserver}',
             'database'=>'{$dbname}',
             'username'=>'{$dbuser}',
             'password'=>'{$dbpass}');
             
define('DATE_FORMAT', 'm/d/Y');
define('TIME_FORMAT', 'h:i A');
";

if(!$db2 = new JDb($cdsn)){
    echo "Cannot connect to db schema info, foreign keys will not be populated\n";
}

echo fitConsole("Creating Dir {$dir}",(@mkdir($dir)?"........OK":"....Failed"))."\n";
echo fitConsole("Creating Dir {$dir}/includes",(@mkdir($dir."/includes")?"........OK":"....Failed"))."\n";
echo fitConsole("Creating Dir {$dir}/templates",(@mkdir($dir."/templates")?"........OK":"....Failed"))."\n";
echo fitConsole("Creating Dir {$dir}/public/css",(@mkdir($dir."/public/css")?"........OK":"....Failed"))."\n";
echo fitConsole("Creating File {$dir}/public/css/main.css",(@copy("{$fromdir}css/main.css",$dir."/public/css/main.css")?"........OK":"....Failed"))."\n";
echo fitConsole("Creating File {$dir}/templates/default.html",(@copy("{$fromdir}default.html",$dir."/templates/default.html")?"........OK":"....Failed"))."\n";
echo fitConsole("Creating Dir {$dir}/pages",(@mkdir($dir."/pages")?"........OK":"....Failed"))."\n";
echo fitConsole("Creating Dir {$dir}/public",(@mkdir($dir."/public")?"........OK":"....Failed"))."\n";
echo fitConsole("Creating File {$dir}/public/index.php",(@copy("{$fromdir}index.php",$dir."/public/index.php")?"........OK":"....Failed"))."\n";
echo fitConsole("Creating File {$dir}/includes/config.inc.php",(@file_put_contents($dir."/includes/config.inc.php", $config))?"........OK":"....Failed")."\n";
echo fitConsole("Creating File {$dir}/includes/jphpframework.php",(@copy("jphpframework.php",$dir."/includes/jphpframework.php"))?"........OK":"....Failed")."\n";

if(Utils::isVal($dbserver) && Utils::isVal($dbname) && Utils::isVal($dbuser) && Utils::isVal($dbpass)){
    if($db = new JDb(array('dbtype'=>'mysqli','host'=>$dbserver,'database'=>$dbname,'username'=>$dbuser,'password'=>$dbpass))){
        $query = "SHOW tables";
        $sres =& $db->select($query);
        while($row =& $sres->fetchRow()){

            $pri = null;
            $cols = array();
            
            //Create the list page
            $list = "<?php\n".
            "if(\$_GET['saved'] == 'true'){\n".
            "   \$content .= \"<h1>Item was saved</h1>\";\n".
            "}else if(\$_GET['saved'] == 'false'){\n".
            "     \$content .= \"<h1>Error saving item</h1>\";\n".
            "}\n\n";
            
            $list .= "\$content .= \"<a href='./'>Back to Menu</a><br /><a href='?page={$row['Tables_in_'.$dbname]}_edit'>Add New</a>\";\n";
            $list .= "\$query = \"SELECT * FROM {$row['Tables_in_'.$dbname]}\";\n\n";
            $list .= "\$res =& \$db->select(\$query);\n";
            $list .= "if(\$res->numRows() > 0){\n";
            $list .= "\t\$content .= \"<div class='list'><table class='listtable'>\";\n";
            
            $query = "SHOW COLUMNS FROM {$row['Tables_in_'.$dbname]}";
            $topres =& $db->select($query);
            
            $list .= "\t\$content .= \"<tr>\";\n";
            while($head =& $topres->fetchRow()){ 
                $cols[] = $head['Field'];
                if($head['Key'] == 'PRI'){
                    $pri = $head['Field'];
                }else{
                    $list .= "\t\$content .= \"<th>".$head['Field']."</th>\";\n";
                }
            }
            $list .= "\t\$content .= \"<th></th></tr>\";\n";
            $list .= "\twhile(\$row =& \$res->fetchRow()){\n";
            $list .= "\t\t\$content .= \"<tr>\";\n";
            $query = "SHOW COLUMNS FROM {$row['Tables_in_'.$dbname]}";
            $datares =& $db->select($query);
            while($col =& $datares->fetchRow()){
                $info = explode("(", $col['Type']);
                $info2 = explode(")", $info[1]);
                $type = $info[0];
                $size = $info2[0];
                if($type == 'date'){
                  $list .= "\t\$content .= \"<td>\".Utils::displaydate(\$row['".$col['Field']."']).\"</td>\";\n";
                }else if(in_array($type, array('datetime', 'timestamp'))){
                  $list .= "\t\$content .= \"<td>\".Utils::displaydate(\$row['".$col['Field']."']).\" \".Utils::displaytime(\$row['".$col['Field']."']).\"</td>\";\n";
                }else if($col['Key'] != "PRI"){
                  $list .= "\t\t\$content .= \"<td>{\$row['".$col['Field']."']}</td>\";\n";
                }
            }
            $list .= "\t\t\$content .= \"<td><a href='?page=".strtolower($row['Tables_in_'.$dbname])."_edit&who={\$row['{$pri}']}'>edit</a></td>\n\";";
            $list .= "\t\t\$content .= \"</tr>\";\n";
            $list .= "\t}\n";
            $list .= "\t\$content .= \"</table></div>\";\n";
            $list .= "}\n\n";
            $list .= "\$tpl->assign('content',\$content);";

            //create the edit page
            $fields = "";
            $dbfields = "";
	        $cquery = "SHOW COLUMNS FROM ?";
	        $eres =& $db->select($cquery, array($row['Tables_in_'.$dbname]));
	        while($trow =& $eres->fetchRow()){
	            $info = explode("(", $trow['Type']);
	            $info2 = explode(")", $info[1]);
	            $type = $info[0];
	            $size = $info2[0];
	            
	            //see if the field is a foreign key
	            $query = "SELECT * FROM KEY_COLUMN_USAGE 
	            WHERE CONSTRAINT_SCHEMA='?'
	            AND TABLE_NAME='?' 
	            AND COLUMN_NAME='?' 
	            AND REFERENCED_COLUMN_NAME <> ''";
	            $fkres =& $db2->select($query, array($dbname,$row['Tables_in_'.$dbname],$trow['Field']));

	            //if it is a foreign key, display a field from the other table
	            if($fkres->numRows() > 0){
	                $fkrow =& $fkres->fetchRow();
	                $query = "SHOW COLUMNS FROM ?";
	                $ffrow = $db->selectAll($query, array($fkrow['REFERENCED_TABLE_NAME']));
	                $fields .= "\$query = \"SELECT * FROM {$fkrow['REFERENCED_TABLE_NAME']}\";\n";
	                $fields .= "\$fkdres =& \$db->select(\$query);\n";
	                $fields .= "while(\$fkdrow =& \$fkdres->fetchRow())";
	                $fields .= " \${$trow['Field']}_values[\$fkdrow['{$fkrow['REFERENCED_COLUMN_NAME']}']] = \$fkdrow['{$ffrow[1]['Field']}'];\n";
	                $fields .= "\$form->addelement('select', '{$trow['Field']}', '{$ffrow[1]['Field']}', \${$trow['Field']}_values);\n";
	                $dbfields .= "\t\$tbl->data['{$trow['Field']}'] = \$_POST['{$trow['Field']}'];\n";
	                
	            //if the field is the primary key, do not display    
	            }else if($trow['Key'] == "PRI"){
	                $pri = $trow['Field'];
	                
	            //display a text box    
	            }else if(in_array($type, array('char','varchar', 'int', 'tinyint', 'smallint', 'mediumint', 'bigint'))){
	                $fields .= "\$form->addelement('text', '{$trow['Field']}', '{$trow['Field']}', array('maxlength'=>'{$size}'));\n";
	                $fields .= "\$form->addrule('{$trow['Field']}', \"You can only enter {$size} characters\", 'maxlength', '{$size}');\n";
	                $dbfields .= "\t\$tbl->data['{$trow['Field']}'] = \$_POST['{$trow['Field']}'];\n";
	                
	            //display a text area
	            }else if(in_array($type, array('text', 'tinytext','blob', 'tinyblob','mediumblob'))){
	                $fields .= "\$form->addelement('textarea', '{$trow['Field']}', '{$trow['Field']}', array('style'=>'width:250px;height:150px;'));\n";
	                $dbfields .= "\t\$tbl->data['{$trow['Field']}'] = \$_POST['{$trow['Field']}'];\n";
	                
	            //display a date input    
	            }else if(in_array($type, array('date'))){
	                $fields .= "\$form->addelement('date', '{$trow['Field']}', '{$trow['Field']}', array('format'=>\"m-d-Y\"));\n";
	                $dbfields .= "\t\$tbl->data['{$trow['Field']}'] = \$_POST['{$trow['Field']}']['Y'].\"-\".\$_POST['{$trow['Field']}']['m'].\"-\".\$_POST['{$trow['Field']}']['d'];\n";
	                
	            //display a date time input
	            }else if(in_array($type, array('datetime'))){
	                $fields .= "\$form->addelement('date', '{$trow['Field']}', '{$trow['Field']}', array('format'=>\"m-d-Y h:i A\"));\n";
	                $dbfields .= "\t\$tbl->data['{$trow['Field']}'] = \$_POST['{$trow['Field']}']['Y'].\"-\".\$_POST['{$trow['Field']}']['m'].\"-\".\$_POST['{$trow['Field']}']['d'].\" \".\$_POST['{$trow['Field']}']['H'].\":\".\$_POST['{$trow['Field']}']['i'].\":\".\$_POST['{$trow['Field']}']['s'];\n";
	                
	            //display a select input
	            }else if(in_array($type, array('enum'))){
	                $fields .= "\$form->addelement('select', '{$trow['Field']}', '{$trow['Field']}', array({$size}));\n";
	                $dbfields .= "\t\$tbl->data['{$trow['Field']}'] = \$_POST['{$trow['Field']}'];\n";
	            }
	            
	            if($trow['Key'] != "PRI" && $trow['Null'] == "NO"){
	                $fields .= "\$form->addrule('{$trow['Field']}', \"Please enter data for this field\", 'required');\n";
	            }
	            
	        }

	        $edit = "<?php\n".
	        "\$content .= \"<a href='./'>Back to Menu</a><br /><a href='./?page=".strtolower($row['Tables_in_'.$dbname])."_list'>Back to List</a>\";\n".
            "\$form = new JForm('{$row['Tables_in_'.$dbname]}', 'post', \"?\".\$_SERVER['QUERY_STRING']);\n".
            "if(Utils::isVal(\$_GET['who'])){\n".
	        "\t\$query = \"SELECT * FROM {$row['Tables_in_'.$dbname]} WHERE {$pri}='?'\";\n".
	        "\t\$res =& \$db->select(\$query, array(\$_GET['who']));\n".
	        "\tif(\$res->numRows() > 0){\n".
	        "\t\t\$row =& \$res->fetchRow();\n".
	        "\t\t\$form->setdefaults(\$row);\n".
	        "\t}\n".
	        "}\n\n";
	        $edit .= $fields;
	        $edit .= "\$form->addelement('submit', 'save', 'Save');\n\n";
	        $edit .= "if(\$form->validate()){\n";
	        $edit .= "\t\$tbl = new JDbTable(\$db, {$row['Tables_in_'.$dbname]}, '{$pri}', \$_GET['who']);\n";
	        $edit .= $dbfields;
            $edit .= "\tif(\$tbl->save()){\n";
            $edit .= "\t\theader(\"Location: ?saved=true\");\n";
            $edit .= "\t}else{\n";
            $edit .= "\t\theader(\"Location: ?saved=false\");\n";
            $edit .= "\t}\n";
            $edit .= "\texit;\n";
	        $edit .= "}\n\n";
	        $edit .= "\$content .= \$form->toHtml();\n";
	        $edit .= "\$tpl->assign('content', \$content);";
            
            echo fitConsole("Creating Dir {$dir}/pages/".$row['Tables_in_'.$dbname],(@mkdir("{$dir}/pages/".$row['Tables_in_'.$dbname])?"........OK":"....Failed"))."\n";
            echo fitConsole("Creating File {$dir}/pages/".$row['Tables_in_'.$dbname]."/list.php",(@file_put_contents("{$dir}/pages/".$row['Tables_in_'.$dbname]."/list.php", $list))?"........OK":"....Failed")."\n";
            echo fitConsole("Creating File {$dir}/pages/".$row['Tables_in_'.$dbname]."/edit.php",(@file_put_contents("{$dir}/pages/".$row['Tables_in_'.$dbname]."/edit.php", $edit))?"........OK":"....Failed")."\n";
        }
    }else{
        echo "Connection Error\n";
    }
}

echo "All Done\n";


function fitConsole($text, $status){
    $textsize = 70;
    if(strlen($text) > $textsize)
        $text = substr($text, 0, $textsize);
    $dots = $textsize - strlen($text);
    for($i = 0; $i < $dots; $i++)
        $text .= ".";
    return $text.$status;
}